ci(docker): assert the SQL drivers are in the published runtime image - #16080
Merged
Conversation
The smoke step proved the CLI resolved but nothing asserted that `pg` and `mysql2` -- which docker/Dockerfile installs and docker/README.md publishes as a maintained promise -- are actually in the built image. The in-repo `check:docs-image-tag` pin cannot see that: it compares the install line against the published table, and both would still agree if the drivers vanished from the image. The probe resolves from inside the global tree (`-w`), which is both how the real boot path resolves the drivers and the only spelling that discriminates: `npm install -g` writes to /usr/local/lib/node_modules, which is not on `require()`'s search path from the image's WORKDIR (/srv/app), and the node:22-slim base sets no NODE_PATH. Verified in both directions against purpose-built images before landing: green with the drivers present, red (`Cannot find module 'pg'`) without. Claude-Session: https://claude.ai/code/session_01PU9zBGbH2s2ZtxSyu963M3 Co-authored-by: Claude <noreply@anthropic.com>
os-steve
marked this pull request as ready for review
September 6, 2026 00:12
os-steve
enabled auto-merge
September 6, 2026 00:12
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #14701
Adds one
docker runto the existing amd64 smoke step in.github/workflows/docker-publish.yml, asserting thatpgandmysql2are actually in the built image.Why this line and not the in-repo pin
check:docs-image-tagcomparesdocker/Dockerfile's install line againstdocker/README.md's published driver table. Both files would still agree if the drivers vanished from the built image, so that gate cannot see this.The regression is not hypothetical.
docker/Dockerfile:46-52records it happening — verified verbatim at this branch's basec463d03e0:@objectstack/driver-sqldeclarespg/mysql2/tediousas optional peer dependencies, npm 7+ skips optional peers, and the resulting tree "died at boot onCannot find module 'pg'". The probe guards the exact regression the install line exists to prevent.The proposed one-liner does not work — it is a constant red
The card suggested:
Measured, that spelling fails identically on an image that has the drivers and one that does not, so it never discriminates and would have broken every release:
/srv/app)exit=1exit=1-w /usr/local/lib/node_modulesexit=0exit=1Cause:
npm install -gwrites to/usr/local/lib/node_modules, which is not onrequire()'s search path from the image'sWORKDIR(/srv/app). Node's global folders are$PREFIX/lib/node, and thenode:22-slimbase sets noNODE_PATH(confirmed against the upstreamnodejs/docker-nodeDockerfile for22/bookworm-slim, which sets onlyNODE_VERSIONandYARN_VERSION).Resolving from inside the global tree is also how the real boot path resolves them:
driver-sqllives in that tree, so it walks up into/usr/local/lib/node_modulesand findspg. The shipped probe reproduces that resolution rather than inventing a second one. The-wflag is load-bearing and the step comment says so, because the obvious "simplification" is the broken form.Reverse reading — taken, both directions
Required as binding by triage. The line as committed was extracted verbatim from the YAML and run under Actions' shell (
bash -e):exit=0exit=1,Error: Cannot find module 'pg'USER node:exit=0/exit=1Vehicle, stated honestly: the two images are purpose-built locally, not the real published image. Container blob reads are refused by this environment's egress policy —
docker pullof bothnode:22-slimandghcr.io/objectstack-ai/objectstackresolves the manifest and then getsForbiddenon the blob CDN — so the real image cannot be pulled or built here. The vehicles replicate the layout that decides the outcome exactly:nodeat/usr/local/bin, globals at/usr/local/lib/node_modules,WORKDIR /srv/app, noNODE_PATH. The outcome is a property of node's resolution algorithm over that layout, which is reproduced faithfully. What is not covered here is the real base image and the realnpm install -g; CI exercises those on the first run.Scope
require()needs no artifact and no database, so the step stays on the right side of the line the existing comment draws.check:docs-image-tagis untouched; it asserts something different and still passes.skip-changeset.Generated by Claude Code